package com.qianli.cashmama.trade.application.snapshot;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.Response;
import com.fqgj.xjd.user.client.enums.AadhaarStatusEnum;
import com.fqgj.xjd.user.client.enums.PanStatusEnum;
import com.fqgj.xjd.user.client.enums.UserKycStatusEnum;
import com.fqgj.xjd.user.client.response.*;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.qianli.cashmama.trade.client.snapshot.UserTradeSnapshotService;
import com.qianli.cashmama.trade.client.snapshot.constant.PhotoTypeConstant;
import com.qianli.cashmama.trade.client.snapshot.enums.PhotoTypeEnum;
import com.qianli.cashmama.trade.client.snapshot.request.KycUpdateRequest;
import com.qianli.cashmama.trade.client.snapshot.request.PhotoUrlRequest;
import com.qianli.cashmama.trade.client.snapshot.request.UserSnapUpdateRequest;
import com.qianli.cashmama.trade.client.snapshot.response.UserSnapInfoResponse;
import com.qianli.cashmama.trade.common.dto.UserTradeSnapshotDto;
import com.qianli.cashmama.trade.common.enums.UserSnapshotInfoTypeEnum;
import com.qianli.cashmama.trade.dao.TBankInfoDao;
import com.qianli.cashmama.trade.dao.TRiskInfoDao;
import com.qianli.cashmama.trade.dao.TTradeDao;
import com.qianli.cashmama.trade.domain.factory.impl.TradeBaseDomainFactoryImpl;
import com.qianli.cashmama.trade.entity.TBankInfoEntity;
import com.qianli.cashmama.trade.entity.TRiskInfoEntity;
import com.qianli.cashmama.trade.entity.TTradeEntity;
import com.qianli.cashmama.trade.integration.user.UserIntegrationService;
import com.qianli.cashmama.trade.integration.user.dto.UserBaseInfoDto;
import com.qianli.cashmama.trade.integration.user.dto.UserTotalInfo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/8/14
 * Time: 下午5:40
 * 交易快照信息查询(用户)
 */
@Service("userTradeSnapshotService")
public class UserTradeSnapshotQueryServiceImpl implements UserTradeSnapshotService {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserTradeSnapshotQueryServiceImpl.class);

    @Autowired
    private TRiskInfoDao riskInfoDao;

    @Autowired
    private TBankInfoDao tBankInfoDao;

    @Autowired
    private TTradeDao tTradeDao;

    @Autowired
    private UserIntegrationService userIntegrationService;


    @Override
    public Response<UserSocialContact> getUserSocialContactByTradeNo(String tradeNo) {
        Response<UserSocialContact> response = new Response<>();
        TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_SOCIAL_CONTACT.getType());
        if (entity == null) {
            return response.ok().putData(null);
        }

        String value = entity.getRiskValue();
        return response.ok().putData(JSON.parseObject(value, UserSocialContact.class));
    }

    @Override
    public Response<UserInfo> getUserInfoByTradeNo(String tradeNo) {
        Response<UserInfo> response = new Response<>();
        TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_INFO.getType());
        if (entity == null) {
            return response.ok().putData(null);
        }

        String value = entity.getRiskValue();
        return response.ok().putData(JSON.parseObject(value, UserInfo.class));
    }

    @Override
    public Response<UserQuotaResponse> getQuota(String tradeNo) {
        Response<UserQuotaResponse> response = new Response<>();
        TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_QUOTA.getType());
        if (entity == null) {
            return response.ok().putData(null);
        }
        return response.ok().putData(JSON.parseObject(entity.getRiskValue(), UserQuotaResponse.class));
    }

    @Override
    public Response<UserBehaviorRegister> getRegisterInfo(String tradeNo) {
        Response<UserBehaviorRegister> response = new Response<>();
        TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_BEHAVIOR.getType());
        if (entity == null) {
            return response.ok().putData(null);
        }
        return response.ok().putData(JSON.parseObject(entity.getRiskValue(), UserBehaviorRegister.class));
    }

    @Override
    public Response<List<UserAuthFaceRecognition>> getFaceRecognitionListByTradeNo(String tradeNo) {
        Response<UserAuthFaceRecognition> response = new Response<>();
        TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_AUTH_FACE_LIST.getType());
        if (entity == null) {
            return response.ok().putData(null);
        }

        JSONArray jsonArray = JSON.parseArray(entity.getRiskValue());
        if (jsonArray == null || jsonArray.size() == 0) {
            return response.ok().putData(null);
        }

        List<UserAuthFaceRecognition> userAuthFaceRecognitionList = new ArrayList<>();
        JSONObject jsonObject = jsonArray.getJSONObject(0);
        UserAuthFaceRecognition userAuthFaceRecognition = jsonObject.toJavaObject(UserAuthFaceRecognition.class);
        userAuthFaceRecognitionList.add(userAuthFaceRecognition);

        return response.ok().putData(userAuthFaceRecognitionList);
    }

    @Override
    public Response<UserBankInfo> getByTradeNo(String tradeNo) {
        Response<UserBankInfo> response = new Response<>();
        TBankInfoEntity entity = tBankInfoDao.selectOneByTradeNo(tradeNo);
        if (entity == null) {
            return response.ok().putData(null);
        }

        TTradeEntity tradeEntity = tTradeDao.selectOneByTradeNo(tradeNo);
        if (tradeEntity == null) {
            return response.ok().putData(null);
        }

        UserBankInfo bankInfo = new UserBankInfo()
                .setCardNo(entity.getCardNo())
                .setCode(entity.getBankType())
                .setMobile(entity.getSignMobile())
                .setName(entity.getBankName())
                .setStatus(1)
                .setType(entity.getBindType())
                .setUserCode(tradeEntity.getUserCode());

        return response.ok().putData(bankInfo);
    }

    @Override
    public Response<Map<String, String>> getUserLatestWifiNameMapByTradeNo(String tradeNo) {
        Response<UserAuthFaceRecognition> response = new Response<>();
        TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_WIFI_MAP.getType());
        if (entity == null) {
            return response.ok().putData(null);
        }

        if (StringUtils.isEmpty(entity.getRiskValue())) {
            return response.ok().putData(null);
        }

        return response.ok().putData((Map) JSON.parse(entity.getRiskValue()));
    }

    @Override
    public Response<UserSnapInfoResponse> getTradeUserSnapInfo(String tradeNo) {
        LOGGER.info("== 重新生成用户的快照信息 ==,tradeNo:{}", tradeNo);
        UserSnapInfoResponse userSnapInfoResponse = new UserSnapInfoResponse();
        UserTradeSnapshotDto userTradeSnapshotInfoByUserCode = null;

        try {
            TTradeEntity tradeEntity = tTradeDao.selectOneByTradeNo(tradeNo);
            TRiskInfoEntity entity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_BASE_SNAP.getType());
            if (entity == null || StringUtils.isEmpty(entity.getRiskValue())) {
                LOGGER.info("== 重新生成用户的快照信息,不存在 ==,tradeNo:{}", tradeNo);
                userTradeSnapshotInfoByUserCode = userIntegrationService.getUserTradeSnapshotInfoByUserCode(tradeEntity.getUserCode(), tradeEntity.getProductCategory());
                UserTotalInfo userTotalInfo = TradeBaseDomainFactoryImpl.createUserTotalInfo(userTradeSnapshotInfoByUserCode);
                if (userTotalInfo == null) {
                    LOGGER.error("== 重新生成用户的快照信息,userTotalInfo为空 ==,tradeNo:{}", tradeNo);
                    return Response.ok().putData(null);
                }

                String name = Joiner.on(" ").skipNulls().join(userTotalInfo.getUserFirstName(), userTotalInfo.getUserMiddleName(), userTotalInfo.getUserLastName());
                TRiskInfoEntity riskInfoEntity = new TRiskInfoEntity()
                        .setTradeNo(tradeNo)
                        .setRiskType(UserSnapshotInfoTypeEnum.USER_BASE_SNAP.getType())
                        .setRiskValue(JSON.toJSONString(userTotalInfo))
                        .setName(CharMatcher.WHITESPACE.collapseFrom(name, ' '))
                        .setEmail(Strings.nullToEmpty(userTotalInfo.getUserEmail()))
                        .setPhone(Strings.nullToEmpty(userTotalInfo.getMobile()));
                LOGGER.info("== 重新生成用户的快照信息,存储 ==,tradeNo:{},entity:{}", tradeNo, JSON.toJSONString(riskInfoEntity));
                userSnapInfoResponse = JSON.parseObject(riskInfoEntity.getRiskValue(), UserSnapInfoResponse.class);
                riskInfoDao.insert(riskInfoEntity);
            } else {
                LOGGER.info("== 重新生成用户的快照信息 存在 ==,tradeNo:{}", tradeNo);
                userSnapInfoResponse = JSON.parseObject(entity.getRiskValue(), UserSnapInfoResponse.class);
            }

            if (userSnapInfoResponse == null) {
                LOGGER.error("== 重新生成用户的快照信息 userSnapInfoResponse为空 ==,tradeNo:{}", tradeNo);
                return Response.ok().putData(null);
            }

            TBankInfoEntity bankInfoEntity = tBankInfoDao.selectOneByTradeNo(tradeNo);
            UserBaseInfoDto userBaseInfoByUserCode = userIntegrationService.getUserBaseInfoByUserCode(tradeEntity.getUserCode(), tradeEntity.getProductCategory());
            BigDecimal userQuota = new BigDecimal(0);
            if (userBaseInfoByUserCode != null) {
                userQuota = userBaseInfoByUserCode.getUserQuota();
            } else {
                LOGGER.info("== 重新生成用户的快照信息 userBaseInfoByUserCode为空 ==,tradeNo:{}", tradeNo);
            }

            userSnapInfoResponse.setBanCardNo(bankInfoEntity.getCardNo())
                    .setBankName(bankInfoEntity.getBankName())
                    .setBankIFSCCode(bankInfoEntity.getBankType())
                    .setQuota(userQuota)
                    .setWifiName("")
                    .setSameWifiUsers(new HashMap<>());
        } catch (Exception e) {
            LOGGER.error("== 重新生成用户的快照信息失败 ==,tradeNo:{},e", tradeNo, e);
        }

        return Response.ok().putData(userSnapInfoResponse);
    }

    @Override
    public Response updateTradeUserSnapInfoUrl(String tradeNo, String type, PhotoUrlRequest photoUrlRequest) {
        TRiskInfoEntity tRiskInfoEntity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_BASE_SNAP.getType());
        if (tRiskInfoEntity == null) {
            LOGGER.info("------ trade risk info not exist, tradeNo:{} ------", tradeNo);
            return Response.ok();
        }
        String riskValue = tRiskInfoEntity.getRiskValue();
        UserTotalInfo userTotalInfo = JSON.parseObject(riskValue, UserTotalInfo.class);
        switch (type) {
            case PhotoTypeConstant.AADHAAR:
                userTotalInfo.getUserAadhaarInfo().setCardFrontUrl(photoUrlRequest.getAadhaarFrontUrl());
                userTotalInfo.getUserAadhaarInfo().setCardBackUrl(photoUrlRequest.getAadhaarBackUrl());
                if (StringUtils.isBlank(photoUrlRequest.getAadhaarFrontUrl())
                        || StringUtils.isBlank(photoUrlRequest.getAadhaarBackUrl())) {
                    userTotalInfo.getUserAadhaarInfo().setStatus(AadhaarStatusEnum.RE_UPLOAD.getStatus());
                }
                break;
            case PhotoTypeConstant.HANDHELD:
                userTotalInfo.getUserAadhaarInfo().setHandheldUrl(photoUrlRequest.getHandheldUrl());
                if (StringUtils.isBlank(photoUrlRequest.getHandheldUrl())) {
                    userTotalInfo.getUserAadhaarInfo().setStatus(AadhaarStatusEnum.RE_UPLOAD.getStatus());
                }
                break;
            case PhotoTypeConstant.SELFIE:
                userTotalInfo.getUserAadhaarInfo().setSelfieUrl(photoUrlRequest.getSelfieUrl());
                if (StringUtils.isBlank(photoUrlRequest.getSelfieUrl())) {
                    userTotalInfo.getUserAadhaarInfo().setStatus(AadhaarStatusEnum.RE_UPLOAD.getStatus());
                }
                break;
            case PhotoTypeConstant.PAN:
                userTotalInfo.getUserPanInfo().setCardUrl(photoUrlRequest.getPanUrl());
                if (StringUtils.isBlank(photoUrlRequest.getPanUrl())) {
                    userTotalInfo.getUserPanInfo().setPanStatus(PanStatusEnum.RE_UPLOAD.getStatus());
                } else {
                    userTotalInfo.getUserPanInfo().setPanStatus(PanStatusEnum.YES.getStatus());
                }
                break;
        }
        if (StringUtils.isNotBlank(userTotalInfo.getUserAadhaarInfo().getCardFrontUrl()) &&
                StringUtils.isNotBlank(userTotalInfo.getUserAadhaarInfo().getCardBackUrl()) &&
                StringUtils.isNotBlank(userTotalInfo.getUserAadhaarInfo().getHandheldUrl())
            //StringUtils.isNotBlank(userTotalInfo.getUserAadhaarInfo().getSelfieUrl())
        ) {
            userTotalInfo.getUserAadhaarInfo().setStatus(AadhaarStatusEnum.CHECK_SUCCESS.getStatus());
        }
        tRiskInfoEntity.setRiskValue(JSON.toJSONString(userTotalInfo));
        riskInfoDao.updateByPrimaryKey(tRiskInfoEntity);
        return Response.ok();
    }

    @Override
    public Response updateTradeUserSnapKycAndPan(String tradeNo, KycUpdateRequest kycUpdateRequest) {
        if (kycUpdateRequest.getPhotoTypeEnum() == null) {
            LOGGER.info("====== update trade user snap parameter lack, PhotoTypeEnum is null ======");
            return Response.error("PhotoTypeEnum is null");
        }

        TRiskInfoEntity tRiskInfoEntity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_BASE_SNAP.getType());
        if (tRiskInfoEntity == null) {
            LOGGER.info("------ trade risk info not exist, tradeNo:{} ------", tradeNo);
            return Response.ok();
        }
        String riskValue = tRiskInfoEntity.getRiskValue();
        UserTotalInfo userTotalInfo = JSON.parseObject(riskValue, UserTotalInfo.class);

        if (userTotalInfo.getUserKycDocumentInfo() == null) {
            userTotalInfo.setUserKycDocumentInfo(new UserKycDocumentInfo());
        }

        if (PhotoTypeEnum.KYC_FRONT_BACK.equals(kycUpdateRequest.getPhotoTypeEnum())) {
            userTotalInfo.getUserKycDocumentInfo().setCardFrontUrl(kycUpdateRequest.getCardFrontUrl());
            userTotalInfo.getUserKycDocumentInfo().setCardBackUrl(kycUpdateRequest.getCardBackUrl());
            if (StringUtils.isBlank(kycUpdateRequest.getCardFrontUrl())
                    || StringUtils.isBlank(kycUpdateRequest.getCardBackUrl())) {
                userTotalInfo.getUserKycDocumentInfo().setStatus(UserKycStatusEnum.RE_UPLOAD);
            }
        } else if (PhotoTypeEnum.HANDHELD.equals(kycUpdateRequest.getPhotoTypeEnum())) {
            userTotalInfo.getUserKycDocumentInfo().setHandHoldUrl(kycUpdateRequest.getHandheldUrl());
            if (StringUtils.isBlank(kycUpdateRequest.getHandheldUrl())) {
                userTotalInfo.getUserKycDocumentInfo().setStatus(UserKycStatusEnum.RE_UPLOAD);
            }
        } else if (PhotoTypeEnum.SELFIE.equals(kycUpdateRequest.getPhotoTypeEnum())) {
            userTotalInfo.getUserKycDocumentInfo().setSelfieUrl(kycUpdateRequest.getSelfieUrl());
            if (StringUtils.isBlank(kycUpdateRequest.getSelfieUrl())) {
                userTotalInfo.getUserKycDocumentInfo().setStatus(UserKycStatusEnum.RE_UPLOAD);
            }
        } else if (PhotoTypeEnum.PAN.equals(kycUpdateRequest.getPhotoTypeEnum())) {
            userTotalInfo.getUserPanInfo().setCardUrl(kycUpdateRequest.getPanUrl());
            if (StringUtils.isBlank(kycUpdateRequest.getPanUrl())) {
                userTotalInfo.getUserPanInfo().setPanStatus(PanStatusEnum.RE_UPLOAD.getStatus());
            } else {
                userTotalInfo.getUserPanInfo().setPanStatus(PanStatusEnum.YES.getStatus());
            }
        } else {
            LOGGER.info("======= update trade user snap, PhotoTypeEnum do not match =======");
        }

        if (StringUtils.isNotBlank(userTotalInfo.getUserKycDocumentInfo().getCardFrontUrl()) &&
                StringUtils.isNotBlank(userTotalInfo.getUserKycDocumentInfo().getCardBackUrl()) &&
                StringUtils.isNotBlank(userTotalInfo.getUserKycDocumentInfo().getHandHoldUrl())
            //StringUtils.isNotBlank(userTotalInfo.getUserKycDocumentInfo().getSelfieUrl())
        ) {
            userTotalInfo.getUserKycDocumentInfo().setStatus(UserKycStatusEnum.CHECK_SUCCESS);
        }

        tRiskInfoEntity.setRiskValue(JSON.toJSONString(userTotalInfo));
        riskInfoDao.updateByPrimaryKey(tRiskInfoEntity);
        return Response.ok();
    }

    @Override
    public Response updateTradeUserSnapBaseInfo(String tradeNo, UserSnapUpdateRequest userSnapUpdateRequest) {
        if (StringUtils.isBlank(userSnapUpdateRequest.getPermanentAddress())
                && StringUtils.isBlank(userSnapUpdateRequest.getCurrentAddress())) {
            LOGGER.info("====== update trade user snap base info parameter lack, address is null ======");
            return Response.error("address is null");
        }

        TRiskInfoEntity tRiskInfoEntity = riskInfoDao.selectOneByTradeNoAndType(tradeNo, UserSnapshotInfoTypeEnum.USER_BASE_SNAP.getType());
        if (tRiskInfoEntity == null) {
            LOGGER.info("------ trade risk info not exist, tradeNo:{} ------", tradeNo);
            return Response.ok();
        }
        String riskValue = tRiskInfoEntity.getRiskValue();
        UserTotalInfo userTotalInfo = JSON.parseObject(riskValue, UserTotalInfo.class);

        if (StringUtils.isNotBlank(userSnapUpdateRequest.getPermanentAddress())) {
            userTotalInfo.setPermanentAddress(userSnapUpdateRequest.getPermanentAddress());
        }

        if (StringUtils.isNotBlank(userSnapUpdateRequest.getCurrentAddress())) {
            userTotalInfo.setLiveAddress(userSnapUpdateRequest.getCurrentAddress());
        }

        tRiskInfoEntity.setRiskValue(JSON.toJSONString(userTotalInfo));
        riskInfoDao.updateByPrimaryKey(tRiskInfoEntity);
        return Response.ok();
    }

}
